﻿
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace MetroNextTools.NBase
{
    public abstract class NControl : Control
    {
        #region Fields
        private string _currentVisualState;
        private bool _isTemplateApplied;
        private bool _isLoaded;
        private byte _visualStateUpdateLock;
        private bool _isFocused;
        #endregion

        #region DependencyProperties

        #region IsFoused Property 当焦点变化时也要更新状态

        public static readonly DependencyProperty IsFocusedProperty =
            DependencyProperty.Register("IsFocused", typeof(bool), typeof(NControl), new PropertyMetadata(false, OnIsFocusChanged));

        private static void OnIsFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NControl ctrl = (NControl)d;
            ctrl._isFocused = (bool)e.NewValue;
            ((NControl)d).UpdateVisualState(ctrl._isLoaded);
        }

        #endregion
       
        #endregion

        #region Properties

        public string CurrentVisualState
        {
            get { return _currentVisualState; }
        }

        public bool IsTemplateApplied
        {
            get { return _isTemplateApplied; }
        }

        public bool IsLoaded
        {
            get { return _isLoaded; }
        }

        public bool IsFocused
        {
            get { return _isFocused; }
            protected set { base.SetValue(IsFocusedProperty, value); }
        }
        #endregion

        #region Constructor

        public NControl()
        {
            this.Loaded += OnLoaded;
            this.Unloaded += OnUnloaded;
            base.IsEnabledChanged += OnIsEnabledChanged;
            this._currentVisualState = string.Empty;
        }

        #endregion

        #region ApplyTemplate

        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            _isTemplateApplied = true;
        }

        #endregion

        #region Method

        protected virtual void OnLoaded(object sender, RoutedEventArgs e)
        {
            this._isLoaded = true;
        }

        protected virtual void OnUnloaded(object sender, RoutedEventArgs e)
        {
            this._isLoaded = false;
        }

        protected override void OnGotFocus(RoutedEventArgs e)
        {
            base.OnGotFocus(e);
            this.IsFocused = true;
        }

        protected override void OnLostFocus(RoutedEventArgs e)
        {
            base.OnLostFocus(e);
            this.IsFocused = false;
        }

        /// <summary>
        /// 当变成可用时，要更新状态
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnIsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            this.UpdateVisualState(this.IsLoaded);
        }

        /// <summary>
        /// 开始更新状态
        /// </summary>
        protected internal void BeginUpdateVisualState()
        {
            this._visualStateUpdateLock++;
        }

        /// <summary>
        /// 更新状态
        /// </summary>
        /// <param name="animate"></param>
        protected internal void UpdateVisualState(bool animate)
        {
            if (!this.CanUpdateVisualState())
            {
                return;
            }
            string visualStateName = this.ComposeVisualStateName();
            if (visualStateName != _currentVisualState)
            {
                _currentVisualState = visualStateName;
                SetVisualState(visualStateName, animate);
            }
        }

        /// <summary>
        /// 结束状态更新
        /// </summary>
        /// <param name="update"></param>
        /// <param name="animate"></param>
        protected internal void EndUpdateVisualState(bool update, bool animate)
        {
            if (this._visualStateUpdateLock > 0)
            {
                this._visualStateUpdateLock--;
            }
            if (update && _visualStateUpdateLock == 0)
            {
                this.UpdateVisualState(animate);
            }
 
        }

        /// <summary>
        /// 测算状态的名称
        /// </summary>
        /// <returns></returns>
        protected virtual string ComposeVisualStateName()
        {
            if (!base.IsEnabled)
            {
                return "Disabled";
            }
            return "Normal";
        }

        /// <summary>
        /// 设置控件的状态
        /// </summary>
        /// <param name="stateName">状态名</param>
        /// <param name="animate">是否动画播放</param>
        protected virtual void SetVisualState(string visualStateName, bool animate)
        {
            string[] array = visualStateName.Split(',');
            for (int i = 0; i < array.Length; i++)
            {
                string stateName = array[i];
                VisualStateManager.GoToState(this, stateName, animate);
            }
        }

        /// <summary>
        /// 判断是否可以更新状态
        /// 只有当模版提供并且状态锁为0时可以更新
        /// </summary>
        /// <returns></returns>
        protected virtual bool CanUpdateVisualState()
        {
            return this._isTemplateApplied && _visualStateUpdateLock == 0;
        }

        #endregion

    }
}
